const replacements: any = {
	'<': '&lt;',
	'>': '&gt;',
	'&': '&amp;',
	'"': '&quot;'
}

// 转义正则表达式
const escapeRegExp = (string: string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')

/**
 * @description 关键字高亮;
 * @description 将需要高亮的文本 包装一层标签和类名 结合`.highlight`样式控制文字颜色
 * @param text 要展示的文本
 * @param keyword 需要高亮的关键字;匹配时会忽略前后空格
 * @returns {string} 返回包含 span.highlight 标签和类名的html片段
 * @author Dear 2023年10月3日
 * @example ```
 * // v-html方式
 * <span v-html="highlight('文本内容', '关键字')" />
 * // 指令方式; 支持响应式关键字 但不支持响应式内容
 * <span v-highlight="'关键字'">这里是需要高亮的文本内容!!内容不支持响应式</span>
 * // 指令方式; 完全支持响应式
 * <span v-highlight="'关键字'" v-text="'这里是需要高亮的文本内容'" />
 * ```
 */
export const highlight = (text: string, keyword: string) => {
	if (!keyword) {
		return text
	}

	// 将危险字符替换为HTML实体
	text = String(text).replace(/[<>]/g, (char) => replacements[char] || char)
	keyword = String(keyword).trim()

	const regex = new RegExp(`(${escapeRegExp(keyword)})`, 'gi')

	return String(text).replace(regex, (match) => `<span class='highlight'>${match}</span>`)
}
